<?php

namespace Catmes\HttpClient;

/**
 * CURL网络请求工具类
 * 上传文件 $postData = ['uploadf' => new CURLFile(getcwd()."/sample_img.jpg")];
 */
class Curl
{

    protected $curlResource;

    /* @var Request $request */
    protected $request;
    /* @var Response $response */
    protected $response;

    protected $fileResource;

    protected $postData=[];

    public function __construct($url, $method='get', $postData=[])
    {
        $this->request = new Request($url, $method);
        $this->postData = $postData;
        if($postData != [] && strtoupper($method) == Request::METHOD_POST){
            $this->request->setPostData($postData);
        }
    }

    public function getCurlInfo(){
        return curl_getinfo($this->curlResource);
    }

    public function downloadFile($filepath){
        $fp = fopen($filepath, 'w');
        $this->fileResource = $fp;
        return $this;
    }

    public function setReferer($url){
        $this->request->setHeader('referer',$url);
        return $this;
    }

    public function cookieSave($filepath=''){
        $this->request->cookieSave($filepath);
        return $this;
    }
    public function cookieRequest($filepath=''){
        $this->request->cookieRequest($filepath);
        return $this;
    }

    /**
     * 是否跟随页面跳转（仅对GET方法有效）。 默认是。
     * POST方法时。 跟随效果，仅仅传递请求头和GET参数。POST请求体数据无法传递
     */
    public function setFollowLocation($follow=true){
        if($this->request->getMethod() == Request::METHOD_POST){
            throw new \Exception('POST方法不可用FollowLocation选项');
        }
        $this->request->followLocation = $follow;
        return $this;
    }
    public function setRequest(Request $request){
        $this->request = $request;
        return $this;
    }
    public function disableSslVerify(){
        $this->request->disableSslVerify();
        return $this;
    }
    public function postJson(){
        $this->request->setPostJson($this->postData);
        return $this;
    }

    public function postUrlEncoded(){
        $this->request->setPostUrlEncoded($this->postData);
        return $this;
    }

    public function setHeader($key, $value){
        $this->request->setHeader($key, $value);
        return $this;
    }

    /**
     * 获取响应对象
     * @return Response
     */
    public function getResponse(){
        if(!$this->response){
            $this->curlExec();
        }
        return $this->response;
    }

    /**
     * 静态GET方法请求
     * @param string $url
     * @return string
     */
    public static function get($url){
        // new static() 返回对象由调用者决定
        $curl = new self($url);
        return $curl->getResponse();
    }

    /**
     * 静态POST方法请求
     * @param string $url
     * @param array $postData
     * @return string
     */
    public static function post($url, $postData=[], $contentType='url_encoded'|'json'){
        $curl = new self($url, 'post', $postData);
        $contentType = strtolower($contentType);
        switch ($contentType){
            case 'url_encoded':
                $curl->postUrlEncoded();
                break;
            case 'json':
                $curl->postJson();
                break;
            default:
                $curl->postUrlEncoded();
        }
        return $curl->getResponse();
    }

    public function __toString(){
        if($this->response instanceof Response){
            return $this->response->getBody();
        }
        return '';
    }

    protected function exePrepare(){
        $ch = curl_init();
        $request = $this->request;
        $headers = $request->getHeaders();
        $method = $request->getMethod();

        curl_setopt($ch, CURLOPT_URL, $request->getUrl());
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);

        if($request->isPost()){
            curl_setopt($ch, CURLOPT_POST, true);
            $postFields = $request->getPostDataForPhpCurl();
            curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
        }
        if($request->sslVerify == false){
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        }
        if($request->cookieSave){
            curl_setopt($ch, CURLOPT_COOKIEJAR, $request->getCookieFile());
        }
        if($request->cookieRequest){
            curl_setopt($ch, CURLOPT_COOKIEFILE, $request->getCookieFile());
        }
        if($request->followLocation){
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
        }

        /**
         * curl_setopt($ch, CURLOPT_FILE, $this->fileResource);
         * CURLOPT_FILE 设置与 CURLOPT_HEADER，CURLOPT_RETURNTRANSFER 设置项冲突！
         */
        curl_setopt($ch, CURLOPT_HEADER, true);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $this->curlResource = $ch;
        return $this;
    }


    public function curlExec(){
        $this->exePrepare();
        $result = curl_exec($this->curlResource);
        $this->response = new Response($result);
        if($this->fileResource){
            fwrite($this->fileResource, $this->response->getBody());
            fclose($this->fileResource);
        }
        return $this;
    }

    public function __destruct(){
        curl_close($this->curlResource);
    }


}


